using System;
using System.Collections.Generic;
using System.ComponentModel;
using CSW.Framework.Common.Binding.Events;
using CSW.Framework.Common.Binding.ValueTypes;

namespace CSW.Framework.Common.Binding.Interfaces
{
    /// <summary>
    /// IBindableObject
    /// </summary>
    public interface IBindableObject : INotifyPropertyChanged, INotifyInvalidData
    {
        /// <summary>
        /// Occurs when a ComplexProperty's ReadOnly value changes.
        /// </summary>
        event ReadOnlyChangedEventHandler ReadOnlyChanged;

        /// <summary>
        /// Occurs when the ObjectState property changes.
        /// </summary>
        event EventHandler ObjectStateChanged;

        /// <summary>
        /// Occurs before the object is refreshed.
        /// </summary>
        event EventHandler BeforeRefresh;

        /// <summary>
        /// Occurs after the object is refreshed;
        /// </summary>
        event EventHandler AfterRefresh;

        /// <summary>
        /// Checks all business rules.
        /// </summary>
        /// <returns><c>true</c> if all rules pass; otherwise, <c>false</c>.</returns>
        bool CheckAllRules();

        /// <summary>
        /// Checks all business rules.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <returns><c>true</c> if all rules pass; otherwise, <c>false</c>.</returns>
        bool CheckAllRules(out string errorMessage);

        /// <summary>
        /// Checks the business rules for a given property.
        /// </summary>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <returns><c>true</c> if rule(s) pass; otherwise, <c>false</c>.</returns>
        bool CheckRules(string propertyName, out string errorMessage);

        /// <summary>
        /// Gets the object's state (Initial, Dirty).
        /// </summary>
        /// <value>The object's state (Initial, Dirty).</value>
        BindableObjectState ObjectState { get; }

        /// <summary>
        /// Gets the detail lists.
        /// </summary>
        /// <value>The detail lists.</value>
        IEnumerable<IChildListProperty> DetailLists { get; }

        /// <summary>
        /// Gets the properties.
        /// </summary>
        /// <value>The properties.</value>
        IComplexPropertyContainer Properties { get; }

        /// <summary>
        /// Tries to save the record's current state as its baseline state.
        /// </summary>
        /// <returns><c>true</c> if successful; otherwise, <c>false</c>.</returns>
        bool TrySaveBaselineState();

        /// <summary>
        /// Tries to save the record's current state as its baseline state.
        /// </summary>
        /// <param name="errorMessage">The error message.</param>
        /// <returns><c>true</c> if successful; otherwise, <c>false</c>.</returns>
        bool TrySaveBaselineState(out string errorMessage);

        /// <summary>
        /// Reverts the object to its baseline state.
        /// </summary>
        void RevertToBaselineState();
    }
}